commonlibsse_ng\re\m\MemoryManager\alloc/scrap_alloc.rs
1//! Scrap heap allocation rust like API(But for reasons of scrap heap reuse, it is a little different)
2use core::alloc::Layout;
3use core::ptr::NonNull;
4
5use crate::re::MemoryManager::MemoryManager;
6use crate::re::ScrapHeap::ScrapHeap;
7use stdx::alloc::AllocError;
8
9/// Attempts to allocate memory using the thread-local scrap heap managed by the custom memory system.
10///
11/// # Errors
12/// Returns a pair of non-null pointers to the scrap heap and the allocated memory on success, or an `AllocError` if allocation fails.
13///
14/// # Safety
15///
16/// - The returned memory is uninitialized.
17/// - The caller must ensure proper usage and deallocation of the returned pointer.
18#[inline]
19pub unsafe fn alloc(layout: Layout) -> Result<(NonNull<ScrapHeap>, NonNull<u8>), AllocError> {
20 unsafe {
21 let mem_manager = MemoryManager::GetSingleton().as_mut().ok_or(AllocError)?;
22
23 let scrap_heap = mem_manager.GetThreadScrapHeap().as_mut().ok_or(AllocError)?;
24 let ptr = scrap_heap.allocate(layout.size(), layout.align()).cast::<u8>();
25
26 NonNull::new(ptr).map(|nn_ptr| (NonNull::from(scrap_heap), nn_ptr)).ok_or(AllocError)
27 }
28}
29
30/// Attempts to allocate zero-initialized memory using the thread-local scrap heap.
31///
32/// # Errors
33/// Returns a pair of non-null pointers to the scrap heap and the allocated memory on success, or an `AllocError` if allocation fails.
34///
35/// # Safety
36///
37/// - The caller must ensure proper usage and deallocation of the returned pointer.
38/// - This function may write zero bytes to uninitialized memory.
39#[inline]
40pub unsafe fn alloc_zeroed(
41 layout: Layout,
42) -> Result<(NonNull<ScrapHeap>, NonNull<u8>), AllocError> {
43 unsafe {
44 let (scrap_heap, ptr) = alloc(layout)?;
45 ptr.as_ptr().write_bytes(0, layout.size());
46 Ok((scrap_heap, ptr))
47 }
48}
49
50/// Attempts to reallocate memory previously allocated from a thread-local scrap heap.
51///
52/// # Errors
53/// Returns a pair of non-null pointers to the scrap heap and the newly allocated memory on success,
54/// or an `AllocError` if reallocation fails.
55///
56/// The old memory region is not automatically copied or deallocated.
57///
58/// # Safety
59///
60/// - `old_ptr` must be a pointer previously returned by [`alloc`] or [`alloc_zeroed`] using the same scrap heap and layout.
61/// - The caller is responsible for copying any existing data and deallocating the old pointer if needed.
62/// - The returned memory is uninitialized.
63///
64/// This function behaves more like a fresh allocation than a standard realloc.
65#[inline]
66pub unsafe fn realloc(
67 mut scrap_heap: NonNull<ScrapHeap>,
68 new_layout: Layout,
69) -> Result<(NonNull<ScrapHeap>, NonNull<u8>), AllocError> {
70 unsafe {
71 let scrap_heap_ref = scrap_heap.as_mut();
72 let new_ptr = scrap_heap_ref.allocate(new_layout.size(), new_layout.align()).cast::<u8>();
73
74 NonNull::new(new_ptr).map(|nn_ptr| (scrap_heap, nn_ptr)).ok_or(AllocError)
75 }
76}
77
78/// Deallocates memory previously allocated using [`alloc`] or [`alloc_zeroed`] with the same scrap heap.
79///
80/// # Safety
81///
82/// - `ptr` must have been returned by a previous call to [`alloc`] or [`alloc_zeroed`] with the same layout and scrap heap.
83/// - Using an invalid pointer or mismatched layout may cause undefined behavior.
84#[inline]
85pub unsafe fn dealloc(mut scrap_heap: NonNull<ScrapHeap>, ptr: NonNull<u8>, layout: Layout) {
86 let _ = layout;
87 unsafe {
88 let scrap_heap = scrap_heap.as_mut();
89 let _ = scrap_heap.deallocate(ptr.cast().as_ptr());
90 }
91}